package com.xuanyue.componentim.datapersistence;

import com.xuanyue.componentim.core.Message;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

/**
 * 缓存通道
 * 消息写入redis之后，批量入库之前，暂存的通道
 */
public interface MessageCacheChannel {


    /* 消息入库指令 */
    String SAVE_MESSAGE_ORDER = "save:mi-#{id},s-#{sendUserId},r-#{retrieveUserId},mc-#{message},t-#{messageTime};";
    /* 消息已读指令 */
    String READ_MESSAGE_ORDER = "read:s-#{sendUserId},r-#{retrieveUserId};";
    /* 消息撤回指令 */
    String RECALL_MESSAGE_ORDER = "recall:mi-#{id};";

    Base64.Encoder encoder = Base64.getEncoder();


    /**
     * 推送消息
     * @param message
     * @return
     */
     default Boolean pushMessage( Message message ){

        String order = SAVE_MESSAGE_ORDER.replace( "#{id}", message.getId() ).
                                          replace( "#{sendUserId}", message.getSendUserId() ).
                                          replace( "#{retrieveUserId}", message.getRetrieveUserId() ).
                                          replace( "#{message}", encoder.encodeToString( message.getMessage().getBytes(StandardCharsets.UTF_8) ) ).
                                          replace( "#{messageTime}", String.valueOf( message.getSendTime().getTime() ) );
        return pushChannel(order);
    }

    /**
     * 推送消息已读
     * @return
     */
    default Boolean pushRead( Message message ){
        return pushRead( message.getSendUserId(), message.getRetrieveUserId() );
    }
    default Boolean pushRead( String sendUserId, String retrieveUserId ){

        String order = READ_MESSAGE_ORDER.replace( "#{sendUserId}", sendUserId ).
                                            replace( "#{retrieveUserId}", retrieveUserId );
        return pushChannel(order);
    }

    /**
     * 推送消息撤回
     * @return
     */
    default Boolean pushRecall( Message message ){
        return pushRecall( message.getId() );
    }
    default Boolean pushRecall( String messageId ){

        String order = RECALL_MESSAGE_ORDER.replace("#{id}", messageId);
        return pushChannel(order);
    }

    /**
     * 暂存消息
     * 将指令存入通道
     * @return
     */
    Boolean pushChannel( String order );

    /**
     * 从通道拉取消息
     * @return
     */
    BatchOrder pullOrder();

    /**
     * 提交批次, 当sql提交成功待commit时会调用
     * 例如 文件缓存则删除文件, redis则清理队列释放锁
     * @param batchId
     * @return
     */
    boolean commitBatch( String batchId );

    /**
     * sql提交失败后调用
     * redis需要释放锁
     * @param batchId
     * @return
     */
    boolean rollbackBatch( String batchId );

}
